<template>
	<view class="waterfalls-box" :style="{ height: height + 'px' }">
		<view
			v-for="(item, index) of list"
			class="waterfalls-list redbor"
			:key="item[idKey]"
			:id="'waterfalls-list-id-' + item[idKey]"
			:ref="'waterfalls-list-id-' + item[idKey]"
			@click="$emit('wapper-lick', item)">
			<image
				class="waterfalls-list-image redbor"
				:class="{ single }"
				mode="widthFix"
				:src="imgUrl + item.img"
				@load="imageLoadHandle(index)"
				@error="imageLoadHandle(index)"
				@click="$emit('image-click', item)" />
			<!-- 	<image
				class="waterfalls-list-image redbor"
				:class="{ single }"
				mode="widthFix"
				:style="imageStyle"
				:src="imgUrl + item[imageSrcKey].split(',')[0] || ' '"
				@load="imageLoadHandle(index)"
				@error="imageLoadHandle(index)"
				@click="$emit('image-click', item)" /> -->
			<slot v-bind="{ item }" />
		</view>
	</view>
</template>
<script>
	export default {
		props: {
			list: { type: Array, required: true },
			// offset 间距，单位为 px
			offset: { type: Number, default: 5 },
			// 列表渲染的 key 的键名，值必须唯一，默认为 id
			idKey: { type: String, default: 'file_id' },
			// 图片 src 的键名
			imageSrcKey: { type: String, default: 'file_img' },
			// 列数
			cols: { type: Number, default: 2, validator: (num) => num >= 2 },
			imageStyle: { type: Object },

			// 是否是单独的渲染图片的样子，只控制图片圆角而已
			single: { type: Boolean, default: false },

			listStyle: { type: Object },
		},
		data() {
			return {
				topArr: [], // left, right 多个时依次表示第几列的数据
				allPositionArr: [], // 保存所有的位置信息
				allHeightArr: [], // 保存所有的 height 信息
				height: 0, // 外层包裹高度
				oldNum: 0,
				num: 0,
				imgUrl: this.imgUrl,
			};
		},
		created() {
			this.refresh();
		},
		methods: {
			imageLoadHandle(index) {
				setTimeout(() => {
					const id = 'waterfalls-list-id-' + this.list[index][this.idKey],
						query = uni.createSelectorQuery().in(this);
					query
						.select('#' + id)
						.fields({ size: true }, (data) => {
							// 获取节点宽高
							this.num++;
							this.$set(this.allHeightArr, index, data.height);
							if (this.num === this.list.length) {
								// 图片载入完毕
								for (let i = this.oldNum; i < this.num; i++) {
									const getTopArrMsg = () => {
										let arrtmp = [...this.topArr].sort((a, b) => a - b);
										return {
											shorterIndex: this.topArr.indexOf(arrtmp[0]), // 高度更低
											shorterValue: arrtmp[0],
											longerIndex: this.topArr.indexOf(arrtmp[this.cols - 1]),
											longerValue: arrtmp[this.cols - 1],
										};
									};
									const { shorterIndex, shorterValue } = getTopArrMsg();
									const position = {
										// 定位
										top: shorterValue + 'px',
										left: (data.width + this.offset) * shorterIndex + 'px',
									};
									this.$set(this.allPositionArr, i, position);
									this.topArr[shorterIndex] =
										shorterValue + this.allHeightArr[i] + this.offset;
									this.height = getTopArrMsg().longerValue - this.offset + 10;
									this.$emit('getHeight', this.height);
								}
								this.oldNum = this.num;
								this.$emit('image-load');
							}
						})
						.exec();
				}, 100);
			},
			refresh() {
				let arr = [];
				for (let i = 0; i < this.cols; i++) {
					arr.push(0);
				}
				this.topArr = arr;
				this.num = 0;
				this.oldNum = 0;
			},
		},
	};
</script>
<style lang="scss" scoped>
	// 这里可以自行配置
	$border-radius: 6px;

	.waterfalls-box {
		position: relative;
		width: 100vw;
		overflow: hidden;
		.waterfalls-list {
			margin-left: 12px;
			width: 300rpx;
			// width: calc((100% - 12 * (2 + 1)) / 2);
			position: absolute;
			background-color: #fff;
			border-radius: $border-radius;
			box-shadow: 0 0 6rpx 2rpx rgba(105, 105, 105, 0.15);
			// 防止刚开始渲染时堆叠在第一幅图的地方
			left: calc(-50% - var(--offset));
			margin-top: 5px;
			.waterfalls-list-image {
				width: 100%;
				will-change: transform;
				border-radius: $border-radius $border-radius 0 0;
				display: block;
				&.single {
					border-radius: $border-radius;
				}
			}
			.masks {
				background: rgba(0, 0, 0, 0.4);
				top: 0;
				left: 0;
				.sold {
					width: 160rpx;
					height: 160rpx;
				}
			}
		}
	}
</style>